//
//$Id: types.cpp 649 2011-02-18 18:30:44Z andrew.tsyganov $
#include "stdafx.h"
#include "include/types.h"
#include "include/sets.h"
#include "include/grids.h"
#include "include/fa.h"
#include "include/utils.h"

using namespace std;

///////////////////////////////////////////////////////////////////////////////
// Label class methods ////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
unsigned Label::serialize(unsigned char* buf) const
{
	unsigned* p = (unsigned*) buf;
	
	u_t n = calc_Size();
	*p++ = (unsigned) n;
	unsigned char* t = (unsigned char*) p;
	
	for (u_t i = 0; i < n; ++i)
	{
		*t++ = (*this)[i];
	}
	
	return (unsigned) (sizeof(unsigned) + n);
}

unsigned Label::deserialize(unsigned char const* buf)
{
	clear();

	unsigned const* p = (unsigned*) buf;
	u_t n = (u_t) *p++;
	unsigned char const* t = (unsigned char const*) p;

	resize(n);
	for (u_t i = 0; i < n; ++i)
	{
		(*this)[i] = *t++;
	}

	return (unsigned) (buf - t);
}

///////////////////////////////////////////////////////////////////////////////
// Bool_Matrix class methods //////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Bool_Matrix::init(u_t const nrows, u_t const ncols)
{
    nrows_ = nrows;
    ncols_ = ncols;
	nones_ = 0;

    (*this).resize(nrows);
    for (u_t i = 0; i < size(); ++i)
    {
        (*this)[i].resize(ncols);
    }
};

void Bool_Matrix::set(u_t i, u_t j)
{
	if ((*this)[i][j] == 0)
	{
		(*this)[i][j] = 1;
		++nones_;
	}
}

void Bool_Matrix::reset(u_t i, u_t j)
{
	if ((*this)[i][j] == 1)
	{
		(*this)[i][j] = 0;
		--nones_;
	}
}

void Bool_Matrix::cover(Grid const& g)
{
	Subset const& r = g.get_Rows();
	Subset const& c = g.get_Columns();
	
	for (Subset::const_iterator it_r = r.begin(); it_r != r.end(); ++it_r)
	{
		for (Subset::const_iterator it_c = c.begin(); it_c != c.end(); ++it_c)
		{
			if ((*this)[*it_r][*it_c] == 1)
			{
				(*this)[*it_r][*it_c] = 0;
				--nones_;
			}
		}
	}
}
/*
void Bool_Matrix::uncover(Grid const& g)
{
	Subset const& r = g.get_Rows();
	Subset const& c = g.get_Columns();
	
	for (Subset::const_iterator it_r = r.begin(); it_r != r.end(); ++it_r)
	{
		for (Subset::const_iterator it_c = c.begin(); it_c != c.end(); ++it_c)
		{
			if ((*this)[*it_r][*it_c] == 0)
			{
				(*this)[*it_r][*it_c] = 1;
				++nones_;
			}
		}
	}
}
*/
///////////////////////////////////////////////////////////////////////////////
// Subset_Matrix class methods ////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void Subset_Matrix::init(u_t const nrows, u_t const ncols)
{
    nrows_ = nrows;
    ncols_ = ncols;

    (*this).resize(nrows);
    for (u_t i = 0; i < size(); ++i)
    {
        (*this)[i].resize(ncols);
    }
};

void Subset_Matrix::clear()
{
    for (u_t i = 0; i < size(); ++i)
    {
        for (u_t j = 0; j < (*this)[i].size(); ++j)
        {
            (*this)[i][j].remove();
        }
    }
}

void Subset_Matrix::remove()
{
    for (u_t i = 0; i < size(); ++i)
    {
        for (u_t j = 0; j < (*this)[i].size(); ++j)
        {
            (*this)[i][j].remove();
        }
    }
}

void Subset_Matrix::cover(Grid const& g, u_t const element)
{
	Subset const& r = g.get_Rows();
	Subset const& c = g.get_Columns();
	
	//cout << g.to_String() << endl;
	//cout << r.to_String() << endl;
	//cout << c.to_String() << endl;

	for (Subset::const_iterator it_r = r.begin(); it_r != r.end(); ++it_r)
	{
		for (Subset::const_iterator it_c = c.begin(); it_c != c.end(); ++it_c)
		{
			(*this)[*it_r][*it_c].insert(element);
		}
	}
}

void Subset_Matrix::cover(std::vector<Grid> const& vg, u_t const fixed_num)
{
	u_t n = vg.size();
	for (u_t i = fixed_num; i < n; ++i)
	{
		cover(vg[i], i - fixed_num);
	}
}

/*
void Subset_Matrix::print_TXT(std::ostream& os) const
{
    u_t m = nrows_;
    u_t n = ncols_;

    // determine maximum width of columns
    u_t max_left_width = IntToString(nrows_ - 1).length();
    vector<u_t> max_columns_width(n);

    for (u_t j = 0; j < n; ++j)
	{
		max_columns_width[j] = IntToString(ncols_ - 1).length();
	}

    for (u_t j = 0; j < n; ++j)
    {
        for (u_t i = 0; i < m; ++i)
        {
            u_t len = (*this)[i][j].to_String().length();
            if (len > max_columns_width[j])
			{
                max_columns_width[j] = len;
			}
        }
    }

	// total width of the table
    u_t total_width = accumulate(max_columns_width.begin(), max_columns_width.end(), 4 + max_left_width + 3 * n);

    // print horizontal line
    PrintLine(os, total_width);

    // print table's header
    os << "|" << setw((streamsize) max_left_width + 3) << " |";
    for (u_t j = 0; j < n; ++j)
	{
		os << setw((streamsize) max_columns_width[j] + 1) << IntToString(j) << " |";
	}
    os << endl;

    // print horizontal line
    PrintLine(os, total_width);

	// print table
    for (u_t i = 0; i < m; ++i)
    {
        // print leftmost column
		os << "| " << setw((streamsize) max_left_width) << IntToString(i) << " |";
        // print matrix
        for (u_t j = 0; j < n; ++j)
		{
            os << setw((streamsize) max_columns_width[j] + 1) << (*this)[i][j].to_String() << " |";
		}
        os << endl;
    }

    // print horizontal line
    PrintLine(os, total_width);
}
*/

//EOF!
